package com.learning.rpc_service.server;

import com.alibaba.fastjson.JSON;
import com.learning.rpc_common.request.RpcRequest;
import com.learning.rpc_service.util.SpringUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.BeansException;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

public class ServerHandler extends ChannelInboundHandlerAdapter {

    private Map<String, Object> serviceMap = new HashMap<>();

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        System.out.println("channelReadMsg:" + msg);
        System.out.println("ChannelHandlerContext:" + ctx);

        // 获取请求参数
        RpcRequest rpcRequest = (RpcRequest) msg;
        // 获取类信息-全限定类名
        String className = rpcRequest.getClassName();
        // 通过spring容器获实例化的类的信息
        setApplicationContext(SpringUtil.getParentBean(Class.forName(className)));
        Object serviceBean = serviceMap.get(className);
        // 获取要执行的方法名
        String methodName = rpcRequest.getMethodName();
        // 获取参数信息
        Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
        // 获取参数
        Object[] parameters = rpcRequest.getParameters();
        // 通过反射创建类
        System.out.println(className);
        Class<?> aClass = Class.forName(className);
        Method method = aClass.getMethod(methodName, parameterTypes);
        method.setAccessible(true);
        Object invoke = method.invoke(serviceBean, parameters);
        System.out.println("invoke：" + invoke);
        ctx.channel().writeAndFlush(invoke);
        return;
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        ctx.channel().close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.channel().close();
    }



    public void setApplicationContext(Map beans) throws BeansException {
        for (Object serviceBean : beans.values()) {
            Class<?> clazz = serviceBean.getClass();
            Class<?>[] interfaces = clazz.getInterfaces();
            for (Class<?> inter : interfaces) {
                String interfaceName = inter.getName();
                System.out.println("加载服务类: {}" + interfaceName);
                serviceMap.put(interfaceName, serviceBean);
            }
        }
        System.out.println("加载服务类: {}" + serviceMap);
    }

    /**
     * 获取参数列表
     *
     * @param parameterTypes
     * @param parameters
     * @return
     */
    private Object[] getParameters(Class<?>[] parameterTypes, Object[] parameters) {
        if (parameters == null || parameters.length == 0) {
            return parameters;
        } else {
            Object[] new_parameters = new Object[parameters.length];
            for (int i = 0; i < parameters.length; i++) {
                new_parameters[i] = JSON.parseObject(parameters[i].toString(), parameterTypes[i]);
            }
            return new_parameters;
        }
    }
}
